/*
 * @author Kansas
 * ICS314 Sundial Project
 *
 * A component that contains a gnomon and a dial plate with hour lines drawn
 * based on the sundialCalculations.
 *
 */

import java.awt.*;
import java.awt.geom.Line2D;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.util.ArrayList;
import javax.swing.*;

public class SundialGnomon extends JFrame implements Printable{
       
        int     panelHeight;
        int     panelWidth;

        boolean passed; // Notes variables were passed
        //Fields for the gnomon
        double  gnomonOriginX;
        double  gnomonOriginY;
       
        double  gnomonEndX;
        double  gnomonEndY;    
       
        double  gnomonEndX2;
        double  gnomonEndY2;
       
        double  gnomonLength;
        double  gnomonAngle;

       
        /*
         * Default Constructor
         */
        public SundialGnomon(){
            //default; should never execute
        setTitle("Face Error");
        setSize(400, 400);
        setVisible(true);
        setBackground(Color.white);
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        passed = false;
        }
       
        /*
         * Constructor:
         * Creates a new SundialOutput and sets its dimensions,
         * the origin and end coordinates of the gnomon base and
         * latitude angle lines, and the origins for the dial plate's
         * hour lines.
         *
         * @param height
         *              The height of the SundialOutput component.
         *              Its width will be set to double this value.
         *              Must be at least 500.
         *
         * @param latitude
         *              The latitude that has been input by the user.
         *              Used to draw the gnomon.
         *              Must be in the 10-80 range.
         *
         *
         * @param angles
         *              The ArrayList containing the angles of the hour lines
         *              to be drawn. Must contain 13 angles, for the hours
         *              6:00-18:00.
         *
         * @param daylight
         *              Whether or not daylight saving is in effect.
         */
        public SundialGnomon(int height, double latitude) throws Exception{
        Dimension size = Toolkit.getDefaultToolkit().getScreenSize();
        setTitle("Sundial Gnomon");
        setSize(size);
        setVisible(true);
        setBackground(Color.white);
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
               
                if(height < 500){
                        throw new Exception("Height must be at least 500");
                }
                if((latitude < 10.0) || (latitude > 80.0)){
                        throw new Exception ("Latitude must be in the range 10 - 80");
                }
               
                panelHeight             = height;
                panelWidth              = 2*height;
        
                gnomonAngle     = latitude;
                gnomonLength    = panelWidth/5.0;
                       
                gnomonOriginX   = panelWidth/6.0;
                gnomonOriginY   = 5.0*(panelHeight/6.0);
               
                gnomonEndX              = gnomonOriginX + gnomonLength;
                gnomonEndY              = gnomonOriginY;
               
                gnomonEndX2     = gnomonOriginX + gnomonLength*1.5 * Math.cos(Math.toRadians(gnomonAngle));
                gnomonEndY2     = gnomonOriginY - gnomonLength*1.5 * Math.sin(Math.toRadians(gnomonAngle));
              
               
                passed                  = true;
        }
       
        /*
         * Draws the gnomon. Includes notes on how the gnomon
         * should be oriented on the dial plate.
         *
         * @param target
         *              The Graphics2D on which to draw the gnomon.
         */
        public void drawGnomon(Graphics2D target){
                target.setColor(Color.red);
                target.draw(new Line2D.Double(gnomonOriginX, gnomonOriginY, gnomonEndX, gnomonEndY));
                       
                target.setColor(Color.black);
                target.draw(new Line2D.Double(gnomonOriginX, gnomonOriginY, gnomonEndX2, gnomonEndY2));
                target.draw(new Line2D.Double(gnomonEndX, gnomonEndY, gnomonEndX2, gnomonEndY2));
               
               
                target.drawString("<< Point towards center of the dial plate", (int) gnomonOriginX, (int) gnomonOriginY + 20);
                target.drawString("Point towards N >>", (int) (gnomonOriginX + gnomonLength/2), (int) gnomonOriginY + 40);      
        }
       
        public void paint (Graphics gr){
                Graphics2D gr2d = (Graphics2D) gr;
               
                setBackground(Color.white);
                gr2d.setColor(Color.black);
                if(passed){
                       
                        drawGnomon(gr2d);
                                                               
                        gr2d.setColor(Color.black);
                
                }
               
               
        }

       
        @Override
        public int print(Graphics graphics, PageFormat pageFormat, int pageIndex)
                        throws PrinterException {

        // Only one page, should not be any more
                // Prevents the infinite printing problem
        if (pageIndex > 0) {
            return NO_SUCH_PAGE;
        }

        // X and Y values are to ensure that the entire area is printed
        Graphics2D g2d = (Graphics2D) graphics;
        g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY());

        // Rendering
        this.paint(g2d);

        // This page exists
        return PAGE_EXISTS;

        }


}
